Imports System.Windows.Forms
Imports WindowsLive.Writer.Api
Imports System.Xml.Linq

<WriterPlugin("812469c5-0cb0-4c63-8c15-c81123a09de7", "SyntaxHighlighter", Description:="Insert code with tags for dp.SyntaxHighlighter.", haseditableoptions:=True, publisherurl:="http://katamari.jp/link.php?syntaxhighlighter", imagepath:="code.ico"), _
InsertableContentSourceAttribute("Code")> _
Public Class SyntaxHighlighter
    Inherits SmartContentSource

    Private Shared Browser As WebBrowser
    Private Shared _dialogOwner As IWin32Window

    Public Overrides Function CreateContent(ByVal dialogOwner As System.Windows.Forms.IWin32Window, ByVal newContent As WindowsLive.Writer.Api.ISmartContent) As System.Windows.Forms.DialogResult

        _dialogOwner = dialogOwner

        Dim code = ""
        If (Options.GetInsertedAction = EditorActions.PasteAndFix OrElse Options.GetInsertedAction = EditorActions.PasteText) AndAlso _
            Clipboard.ContainsText Then
            code = Clipboard.GetText
        End If

        Dim frm = New EditForm(Options.GetLanguage, code)
        frm.SetTabSize(Options.GetTabSize)
        If Options.GetInsertedAction = EditorActions.PasteAndFix Then
            frm.FixIndent()
        End If

        Dim result = frm.ShowDialog(dialogOwner)
        If result = DialogResult.OK AndAlso frm.Code.Trim <> "" Then

            newContent.Properties.SetLanguage(frm.Language)
            newContent.Properties.SetCode(frm.Code)

            newContent.Properties.SetNoGutter(Options.GetNoGutter)
            newContent.Properties.SetNoControls(Options.GetNoControls)
            newContent.Properties.SetCollapse(Options.GetCollapse)
            newContent.Properties.SetFirstLine(Options.GetFirstLine)
            newContent.Properties.SetShowColumns(Options.GetShowColumns)
            newContent.Properties.SetLineValue(Options.GetLineValue)

        Else
            result = DialogResult.Cancel
        End If

        frm.Dispose()
        Return result

    End Function


    Public Overrides Function CreateEditor(ByVal editorSite As WindowsLive.Writer.Api.ISmartContentEditorSite) As WindowsLive.Writer.Api.SmartContentEditor
        Dim editor As New PropertiesPanelEditor() With {.DialogOwner = _dialogOwner, .PluginOptions = Options}
        Return editor
    End Function


    Public Overrides Function GeneratePublishHtml(ByVal content As WindowsLive.Writer.Api.ISmartContent, ByVal publishingContext As WindowsLive.Writer.Api.IPublishingContext) As String

        Return GetPublishHtml(content)

    End Function


    Private Function GetPublishHtml(ByVal content As WindowsLive.Writer.Api.ISmartContent) As String

        If content Is Nothing Then
            Return ""
        End If

        ' Creating class value
        Dim classValue = New Text.StringBuilder

        With content.Properties
            classValue.Append(.GetLanguage)
            classValue.Append(If(.GetNoGutter, ":nogutter", ""))
            classValue.Append(If(.GetNoControls, ":nocontrols", ""))
            classValue.Append(If(.GetCollapse, ":collapse", ""))

            If .GetFirstLine Then
                classValue.Append(String.Format(":firstline[{0}]", .GetLineValue))
            End If

            classValue.Append(If(.GetShowColumns, ":showcolumns", ""))

        End With

        ' Creating pre tag
        Dim code = content.Properties.GetCode.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;")
        Dim html = String.Format("<pre name=""code"" class=""{0}"">{1}</pre>", classValue.ToString, code)

        Return html

    End Function


    Private Shared Function GetEditorHtml(ByVal content As WindowsLive.Writer.Api.ISmartContent, ByVal publishHtml As String) As String

        Dim html = New System.Text.StringBuilder
        html.Append("<head>")
        html.Append("<script type=""text/javascript"">")
        html.Append(PluginSetting.ReadCoreFile)
        html.Append(PluginSetting.ReadLanguageJSFile(content.Properties.GetLanguage))
        html.Append("</script>")
        html.Append("</head>")

        html.Append("<BODY>")
        html.Append(publishHtml)
        html.Append("<SCRIPT type=""text/javascript"">dp.SyntaxHighlighter.HighlightAll('code');</SCRIPT>")
        html.Append("</BODY>")


        ' Getting HTML by JavaScript using WebBrowser
        Dim result As String
        Try
            If Browser Is Nothing Then
                Browser = New WebBrowser
                Browser.ScriptErrorsSuppressed = True
            End If

            If Browser.Document Is Nothing Then
                Browser.DocumentText = html.ToString
            End If

            Browser.Document.OpenNew(True)
            Browser.Document.Write(html.ToString)

            Dim outer = Browser.Document.Body.OuterHtml
            Dim bodyStart As Integer = outer.IndexOf("<BODY>")
            result = outer.Substring(bodyStart + "<BODY>".Length, outer.LastIndexOf("<SCRIPT") - "<SCRIPT".Length - 1)

        Catch ex As Exception
#If DEBUG Then
            MessageBox.Show(ex.ToString)
#End If
            result = publishHtml
        End Try

        Return result

    End Function


    Public Overrides Function GenerateEditorHtml(ByVal content As WindowsLive.Writer.Api.ISmartContent, ByVal publishingContext As WindowsLive.Writer.Api.IPublishingContext) As String

        Static previousProperties As IProperties = Nothing
        Static previousHtml As String = Nothing

        With content.Properties

            If previousProperties IsNot Nothing AndAlso _
                previousProperties.GetLanguage = .GetLanguage AndAlso _
                previousProperties.GetCode = .GetCode AndAlso _
                previousProperties.GetNoGutter = .GetNoGutter AndAlso _
                previousProperties.GetNoControls = .GetNoControls AndAlso _
                previousProperties.GetCollapse = .GetCollapse AndAlso _
                previousProperties.GetFirstLine = .GetFirstLine AndAlso _
                previousProperties.GetShowColumns = .GetShowColumns AndAlso _
                previousProperties.GetLineValue = .GetLineValue Then

                Return previousHtml
            End If

        End With

        Dim html = GetEditorHtml(content, GetPublishHtml(content))
        previousProperties = content.Properties
        previousHtml = html

        Return html

    End Function

    Public Overrides Sub EditOptions(ByVal dialogOwner As System.Windows.Forms.IWin32Window)

        Dim frm = New OptionForm(Options)
        frm.ShowDialog(dialogOwner)
        frm.Dispose()

    End Sub



End Class
